<?php

/**
 * Class self
 * mysql数据库驱动
 */
class _mysql implements BaseSqlDriver {

    /**
     * 数据库连接池
     */
    private $query_connection = null;

    /**
     * 上一个连接
     */
    private $last_connection = null;
    private $config = null;

    /**
     * 从连接池中获得一个链接用于查询
     */

    private function get_connection($query_connection) {
        if (!$query_connection) {
            $config = RCore::get_db_config();
            $connection = mysql_connect($config['db_host'] . ':' . $config['db_port'], $config['db_user'], $config['db_pass']);
            mysql_select_db($config['db_name'], $connection);
            mysql_query("set names " . $config['db_charset'], $connection);
            return $connection;
        }
        if ($this->query_connection == null) {
            $this->query_connection = $this->get_connection(false);
        }
        return $this->query_connection;
    }


    /**
     * @param $sql
     * 统一接口，返回一个二维关系数组
     */
    public function query($sql) {
        $connection = $this->get_connection(false);
        $res = mysql_query($sql, $connection);
        if (!mysql_num_rows($res)) {
            return null;
        }
        $ret = array();
        while ($row = mysql_fetch_assoc($res)) {
            $ret[] = $row;
        }
        return $ret;
    }

    public function execute($sql) {
        if ($this->last_connection != null) {
            mysql_close($this->last_connection);
        }
        $this->last_connection = $connection = $this->get_connection(false);
        $ret = mysql_query($sql, $connection);
        return $ret;
    }

    public function get_last_inster_id() {
        return mysql_insert_id($this->last_connection);
    }

    public function get_table_struct($table_name) {
        $ret = @$this->query("desc " . $table_name);
        if (!$ret) {
            return $ret;
        }
        $struct = new stdClass();
        $struct->fields = array();
        foreach ($ret as $item) {
            if ($item['Key'] == 'PRI') {
                $struct->pri_key = $item['Field'];
            }
            $struct->fields[] = array(
                'name' => $item['Field'],
                'type' => $item['Type']
            );
        }
        return $struct;
    }

    public function load_config($config) {
        $this->config = $config;
    }


    public function count($res = null) {
        return mysql_num_rows($res);
    }

    /**
     * 得到所有表
     */
    public function get_all_table() {
        $sql = "show tables";
        $res = $this->query($sql);
        $ret = array();
        foreach ($res as $item) {
            foreach ($item as $table) {
                $ret[] = $table;
            }
        }
        return $ret;
    }

    private function get_table_pri_key($table) {
        static $tables = array();
        if (!isset($tables[$table])) {
            $tables[$table] = $this->get_table_struct($table);
        }
        return $tables[$table]->pri_key;

    }

    /**
     * 查询最后的一个ID
     */
    public function get_latest_id($table_name) {
        $pri_key = $this->get_table_pri_key($table_name);
        $res = $this->query("select $pri_key as pri_key from $table_name order by pri_key desc limit 1");
        if (count($res)) {
            return $res[0]['pri_key'];
        }
        //没有的情况，返回0
        return 0;
    }

    public function create_table($table_name, $table_info) {

        $sql = "create table `{$table_name}`(";
        foreach ($table_info->fields as $key => $field) {
            print_R($field);
            $buffer[] = "`{$field['name']}` {$field['type']}" . ($key == 0 ? ' NOT NULL ' : '');
        }

        $buffer[] = "PRIMARY KEY(`{$table_info->pri_key}`)";
        $sql .= implode(' , ', $buffer) . ') DEFAULT CHARSET = ' . $this->config['db_charset'];
        return $this->execute($sql);
    }

    public function table_exists($table_name) {
        $sql = "show tables like '$table_name'";
        $res = $this->query($sql);
        return count($res);
    }

    public function drop_table($table_name) {
        if ($this->table_exists($table_name)) {
            $sql = "DROP TABLE IF EXISTS `$table_name`";
            return self::execute($sql);
        }
        return false;
    }

    public function sync_table($table_name, $table_info) {
        if (!$this->table_exists($table_name)) {
            $this->create_table($table_name, $table_info);
        } else {
            $struct = $this->get_table_struct($table_name);
            $old_fields = array();
            $new_fields = array();
            foreach ($struct->fields as $old_item) {
                $old_fields[$old_item['name']] = $old_item['type'];
            }
            foreach ($table_info->fields as $new_item) {
                $new_fields[$new_item['name']] = $new_item['type'];
            }

            foreach ($old_fields as $name => $type) {
                if (!isset($new_fields[$name])) {
                    $sql = "ALTER TABLE `$table_name` DROP COLUMN `$name`";
                    $this->execute($sql);
                }
            }

            foreach ($new_fields as $name => $type) {
                if (!isset($old_fields[$name])) {
                    $sql = "ALTER TABLE `$table_name` ADD COLUMN `$name` $type";
                    $this->execute($sql);
                } else if ($old_fields[$name] != $type) {
                    $sql = "ALTER TABLE `$table_name` MODIFY COLUMN `$name` $type";
                    $this->execute($sql);
                }
            }


            if ($struct->pri_key != $table_info->pri_key) {
                if (isset($struct->pri_key)) {
                    $sql = "ALTER TABLE `$table_name` DROP PRIMARY KEY";
                    $this->execute($sql);
                }
                $sql = "ALTER TABLE `$table_name` ADD PRIMARY KEY(`{$table_info->pri_key}`)";
                $this->execute($sql);

            }

        }
    }
}
